﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using LibreHardwareMonitor.Hardware;
using WWLauncher.Constant;
using WWLauncher.Util;
using WWLauncher.ViewModel;
using static WWLauncher.Util.HideWindowUtil;
using Computer = LibreHardwareMonitor.Hardware.Computer;

namespace WWLauncher.View
{
    /// <summary>
    /// NotifyWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MonitorWindow : Window
    {
        public MonitorViewModel vm = new();
        private readonly System.Timers.Timer _timer;
        private UpdateVisitor updateVisitor;
        private readonly Computer computer;
        public MonitorWindow()
        {
            this.DataContext = vm;
            InitializeComponent();

            this.Dispatcher.BeginInvoke(() =>
            {
                var taskbarState = TaskbarService.GetWinTaskbarState();
                switch (taskbarState.TaskbarPosition)
                {
                    case TaskbarPosition.Left:
                        Left = (taskbarState.TaskbarSize.Right / this.DpiWidthFactor()) - 20;
                        Top = (taskbarState.TaskbarSize.Bottom / this.DpiHeightFactor()) - Height;
                        break;
                    case TaskbarPosition.Right:
                        Left = (taskbarState.TaskbarSize.Left / this.DpiWidthFactor()) - Width - 20;
                        Top = (taskbarState.TaskbarSize.Bottom / this.DpiHeightFactor()) - Height;
                        break;
                    case TaskbarPosition.Top:
                        Left = (taskbarState.TaskbarSize.Right / this.DpiWidthFactor()) - Width - 20;
                        Top = (taskbarState.TaskbarSize.Bottom / this.DpiHeightFactor());
                        break;
                    case TaskbarPosition.Bottom:
                        Left = (taskbarState.TaskbarSize.Right / this.DpiWidthFactor()) - Width - 20;
                        Top = (taskbarState.TaskbarSize.Top / this.DpiHeightFactor()) - Height;
                        break;
                }

            });
            _timer = new System.Timers.Timer
            {
                Interval = 100
            };
            _timer.Elapsed += _timer2_Tick;
            computer = new Computer
            {
                IsCpuEnabled = true,
                IsGpuEnabled = true,
                IsMemoryEnabled = true,
                IsMotherboardEnabled = false,
                IsControllerEnabled = false,
                IsNetworkEnabled = true,
                IsStorageEnabled = false,
                IsPsuEnabled = false,
                IsBatteryEnabled = false
            };
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        { 
            //获得当前登录的Windows用户标示
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            //判断当前登录用户是否为管理员
            if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
            {
#if !DEBUG
                Restart();
#endif
                vm.IsAdministrator = false;
                vm.AdministratorVisibility = Visibility.Visible;
                vm.FrequencyVisibility = Visibility.Collapsed;

            }

            vm.OneColumnDefinition = 0;

            Task.Run(() =>
            {
                updateVisitor = new UpdateVisitor();
                computer.Open();
                _timer.Start();
            }).ContinueWith(m =>
            {
                _timer.Interval = 1000;
            });
            WindowInteropHelper wndHelper = new WindowInteropHelper(this);

            int exStyle = (int)GetWindowLong(wndHelper.Handle, (int)GetWindowLongFields.GWL_EXSTYLE);

            exStyle |= (int)ExtendedWindowStyles.WS_EX_TOOLWINDOW;
            SetWindowLong(wndHelper.Handle, (int)GetWindowLongFields.GWL_EXSTYLE, (IntPtr)exStyle);

            BGSettingUtil.BGSetting(BGBorder);
        }

        private void _timer2_Tick(object sender, EventArgs e)
        {
            computer.Accept(updateVisitor);
            //StringBuilder sb = new StringBuilder();
            foreach (var hardwareItem in computer.Hardware)
            {
                if (hardwareItem.HardwareType == HardwareType.Network)
                {
                    if (hardwareItem.Name != "WLAN")
                    {
                        continue;
                    }

                    foreach (var sensor in hardwareItem.Sensors)
                    {
                        if (sensor.SensorType != SensorType.Throughput)
                        {
                            continue;
                        }
                        //sb.AppendLine(sensor.Name + "的\t" + sensor.SensorType + "是" + sensor.Value);
                        if (sensor.Name == "Upload Speed")
                        {
                            if (sensor.Value != null)
                                vm.SendingText = ChangeSpeed((float)sensor.Value);
                        }
                        if (sensor.Name == "Download Speed")
                        {
                            if (sensor.Value != null)
                                vm.ReceiveText = ChangeSpeed((float)sensor.Value);
                        }
                    }
                }
            }
            foreach (var hardwareItem in computer.Hardware)
            {
                foreach (var sensor in hardwareItem.Sensors)
                {
                    //sb.AppendLine(sensor.Name + "的\t" + sensor.SensorType + "是" + sensor.Value);

                    if (sensor.Name == "CPU Package" && sensor.SensorType == SensorType.Temperature)
                    {
                        if (sensor.Value != null) vm.CpuTemperature = (float)sensor.Value;
                    }
                    if (sensor.Name == "GPU Core" && sensor.SensorType == SensorType.Temperature)
                    {
                        if (sensor.Value != null) vm.GpuTemperature = (float)sensor.Value;
                    }

                    if (sensor.Name == "D3D 3D")
                    {
                        if (sensor.Value != null) vm.GpuUsage = (float)sensor.Value / 100;
                    }

                    if (sensor.Name == "CPU Total")
                    {
                        if (sensor.Value != null) vm.CpuUsage = (float)sensor.Value / 100;
                    }
                    if (sensor.Name == "Memory")
                    {
                        if (sensor.Value != null) vm.MemoryUsage = (float)sensor.Value / 100;
                    }
                }

                var cpuClock = hardwareItem.Sensors.Where(x => x.SensorType == SensorType.Clock && x.Name.StartsWith("CPU Core")).Select(x => x.Value).Max();
                if (cpuClock != null)
                    vm.CpuClock = Convert.ToInt32(cpuClock);

            }
        }
        private string ChangeSpeed(float size)
        {
            if (0 == size)
            {
                return "0 KB";
            }
            var _size = Math.Round(Convert.ToDouble(size / 1024), 4);
            if (0 < _size && _size < 1024)
            {
                if (_size < 1024)
                {
                    return _size.ToString("0.## KB");
                }
            }
            if (_size >= 1024)
            {
                _size = _size / 1024;
                return _size.ToString("0.## MB");
            }
            return "";
        }
        private void DragMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                DragMove();
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //computer.Close();
            _timer.Stop();
        }



        private void Image_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                Restart();
            }
        }

        private void Restart()
        {
            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.UseShellExecute = true;
                startInfo.FileName = Constants.AppExe;
                startInfo.WorkingDirectory = Constants.AppDir;
                startInfo.Verb = "runas";
                startInfo.Arguments = "-restart";

                var _proc = new Process();
                _proc.StartInfo = startInfo;

                if (!_proc.Start())
                {
                    MessageBox.Show("重启失败。");
                    return;
                }

                Application.Current.Shutdown();
            }
            catch (Exception ex)
            {
                LogUtil.WriteErrorLog(ex);
                return;
            }
        }

        private void Grid_MouseEnter(object sender, MouseEventArgs e)
        {
            vm.BtnColVisibility = Visibility.Visible;
            vm.OneColumnDefinition = 30;
            this.Width += 30;
            this.Left -= 30;
        }

        private void Grid_MouseLeave(object sender, MouseEventArgs e)
        {
            vm.BtnColVisibility = Visibility.Collapsed;
            vm.OneColumnDefinition = 0;
            this.Width -= 30;
            this.Left += 30;
        }

        private void OnTop_MouseDown(object sender, MouseButtonEventArgs e)
        {
            vm.OnTop = !vm.OnTop;
            if (vm.OnTop)
                vm.OnTopSource = "/Resource/Icon/置顶.ico";
            else
                vm.OnTopSource = "/Resource/Icon/非置顶.ico";

        }

        private void CloseMonitor_MouseDown(object sender, MouseButtonEventArgs e)
        {
            var appConfig = MainViewModel.Instance().AppConfig;
            appConfig.IsMonitor = false;

        }
    }
}